/*
 * Copyright 2013 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.gradle.testing.jacoco.tasks;

import groovy.lang.Closure;
import org.gradle.api.Action;
import org.gradle.api.provider.Property;
import org.gradle.api.reporting.Reporting;
import org.gradle.api.specs.Spec;
import org.gradle.api.tasks.CacheableTask;
import org.gradle.api.tasks.Input;
import org.gradle.api.tasks.Nested;
import org.gradle.api.tasks.TaskAction;
import org.gradle.internal.jacoco.AntJacocoReport;
import org.gradle.internal.jacoco.JacocoReportsContainerImpl;
import org.gradle.util.internal.ClosureBackedAction;

import java.io.File;

/**
 * Task to generate HTML, Xml and CSV reports of Jacoco coverage data.
 */
@CacheableTask
public class JacocoReport extends JacocoReportBase implements Reporting<JacocoReportsContainer> {

    private final Property<String> projectName = getProject().getObjects().property(String.class);
    private final JacocoReportsContainer reports;

    public JacocoReport() {
        super();
        projectName.value(getProject().getName()).disallowChanges();
        reports = getInstantiator().newInstance(JacocoReportsContainerImpl.class, this, getCallbackActionDecorator());
    }

    /**
     * The reported project name.
     *
     * @return the reported project name
     * @since 6.4
     */
    @Input
    public Property<String> getReportProjectName() {
        return projectName;
    }

    /**
     * Returns the reports to be generated by this task.
     */
    @Nested
    @Override
    public JacocoReportsContainer getReports() {
        return reports;
    }

    /**
     * Configures the reports to be generated by this task.
     */
    @Override
    public JacocoReportsContainer reports(Closure closure) {
        return reports(new ClosureBackedAction<JacocoReportsContainer>(closure));
    }

    @Override
    public JacocoReportsContainer reports(Action<? super JacocoReportsContainer> configureAction) {
        configureAction.execute(reports);
        return reports;
    }

    @TaskAction
    public void generate() {
        final Spec<File> fileExistsSpec = new Spec<File>() {
            @Override
            public boolean isSatisfiedBy(File file) {
                return file.exists();
            }
        };

        new AntJacocoReport(getAntBuilder()).execute(
            getJacocoClasspath(),
            projectName.get(),
            getAllClassDirs().filter(fileExistsSpec),
            getAllSourceDirs().filter(fileExistsSpec),
            getExecutionData(),
            getReports()
        );
    }
}
